package com.cjt2325.cameralibrary.util;

import static ohos.bundle.IBundleManager.PERMISSION_GRANTED;

import ohos.app.Context;
import ohos.media.audio.AudioCapturer;
import ohos.media.audio.AudioCapturerInfo;
import ohos.media.audio.AudioStreamInfo;
import ohos.security.SystemPermission;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;

/**
 * Check Permission
 */
public class CheckPermission {
    /**
     * STATE RECORDING
     */
    public static final int STATE_RECORDING = -1;

    /**
     * STATE NO_PERMISSION
     */
    public static final int STATE_NO_PERMISSION = -2;

    /**
     * STATE SUCCESS
     */
    public static final int STATE_SUCCESS = 1;

    /**
     * STATE ERROR
     */
    public static final int STATE_ERROR = -2;

    private static List<String> sPermissions =
            new LinkedList<>(
                    Arrays.asList(
                            SystemPermission.WRITE_USER_STORAGE, SystemPermission.CAMERA, SystemPermission.MICROPHONE));

    /**
     * 用于检测是否具有录音权限
     *
     * @return int
     */
    public static int getRecordState() {
        int minBuffer =
                AudioCapturer.getMinBufferSize(
                        44100,
                        AudioStreamInfo.getChannelCount(AudioStreamInfo.ChannelMask.CHANNEL_IN_MONO),
                        AudioStreamInfo.EncodingFormat.ENCODING_PCM_16BIT.getValue());
        if (minBuffer <= 0) {
            return STATE_ERROR;
        }
        AudioStreamInfo.Builder aBuilder = new AudioStreamInfo.Builder();
        aBuilder.channelMask(AudioStreamInfo.ChannelMask.CHANNEL_IN_MONO);
        aBuilder.encodingFormat(AudioStreamInfo.EncodingFormat.ENCODING_PCM_16BIT);
        aBuilder.sampleRate(44100);

        AudioCapturerInfo.Builder builder = new AudioCapturerInfo.Builder();
        builder.audioInputSource(AudioCapturerInfo.AudioInputSource.AUDIO_INPUT_SOURCE_DEFAULT);
        builder.bufferSizeInBytes(minBuffer * 100);
        builder.audioStreamInfo(aBuilder.build());

        AudioCapturer audioRecord = new AudioCapturer(builder.build());

        return handAudioRecord(minBuffer, audioRecord);
    }

    private static int handAudioRecord(int minBuffer, AudioCapturer audioCapturer) {
        AudioCapturer audioRecord = audioCapturer;
        short[] point = new short[minBuffer];
        int readSize;
        try {
            audioRecord.start(); // 检测是否可以进入初始化状态
        } catch (Exception e) {
            if (audioRecord != null) {
                audioRecord.release();
                audioRecord = null;
            }
            return STATE_NO_PERMISSION;
        }
        if (audioRecord.getState() != AudioCapturer.State.STATE_RECORDING) {
            // 6.0以下机型都会返回此状态，故使用时需要判断bulid版本
            // 检测是否在录音中
            if (audioRecord != null) {
                audioRecord.stop();
                audioRecord.release();
                audioRecord = null;
                LogUtil.debug(LogUtil.DEFAULT_TAG, "The recorder is in use");
            }
            return STATE_RECORDING;
        } else {
            // 检测是否可以获取录音结果
            readSize = audioRecord.read(point, 0, point.length);
            if (readSize <= 0) {
                if (audioRecord != null) {
                    audioRecord.stop();
                    audioRecord.release();
                    audioRecord = null;
                }
                LogUtil.error(LogUtil.DEFAULT_TAG, "audioRecord result is empty");
                return STATE_NO_PERMISSION;
            } else {
                if (audioRecord != null) {
                    audioRecord.stop();
                    audioRecord.release();
                    audioRecord = null;
                }
                return STATE_SUCCESS;
            }
        }
    }

    /**
     * 权限检查
     *
     * @param context Context
     * @return boolean
     */
    public static boolean checkPermission(Context context) {
        if (context == null) {
            return false;
        }
        List<String> permissions = new ArrayList<>(sPermissions);
        permissions.removeIf(ss -> context.verifySelfPermission(ss) == PERMISSION_GRANTED);
        return permissions.isEmpty();
    }
}
